package com.sherllinhe.business.service;

import cn.hutool.core.date.DateTime;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.sherllinhe.business.domain.ConfirmOrder;
import com.sherllinhe.business.dto.ConfirmOrderMQDdto;
import com.sherllinhe.business.enums.ConfirmOrderStatusEnum;
import com.sherllinhe.business.enums.RocketMQTopicEnum;
import com.sherllinhe.business.mapper.ConfirmOrderMapper;
import com.sherllinhe.business.req.ConfirmOrderDoReq;
import com.sherllinhe.common.context.LoginMemberContext;
import com.sherllinhe.common.exception.BusinessException;
import com.sherllinhe.common.exception.BusinessExceptionEnum;
import com.sherllinhe.common.util.SnowUtil;
import jakarta.annotation.Resource;
import lombok.Data;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 功能：
 * 作者：Sherllin He
 * 日期：2025/7/10 21:51
 */
@Slf4j
@Service
public class BeforeConfirmOrderService {
    @Autowired
    private SkTokenService skTokenService;
    @Resource
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private ConfirmOrderMapper confirmOrderMapper;
    public Long beforeConfirmOrder(ConfirmOrderDoReq  req) throws InterruptedException {

        req.setMemberId(LoginMemberContext.getId());

        //校验令牌余量
        boolean validSkToken = skTokenService.validSkToken(req.getDate(), req.getTrainCode(), req.getMemberId());
        if(validSkToken){
            log.info("校验令牌通过");
        }else{
            log.info("校验令牌不通过");
            throw new BusinessException(BusinessExceptionEnum.CONFIRM_ORDER_SK_TOKEN_FAIL);
        }

        //保存订单信息到confirm_order表，状态初始
        Date now = DateTime.now();
        ConfirmOrder confirmOrder = new ConfirmOrder();
        confirmOrder.setId(SnowUtil.getSnowflakeNextId());
        confirmOrder.setCreateTime(now);
        confirmOrder.setUpdateTime(now);
        confirmOrder.setMemberId(req.getMemberId());
        confirmOrder.setDate(req.getDate());
        confirmOrder.setTrainCode(req.getTrainCode());
        confirmOrder.setStart(req.getStart());
        confirmOrder.setEnd(req.getEnd());
        confirmOrder.setDailyTrainTicketId(req.getDailyTrainTicketId());
        confirmOrder.setStatus(ConfirmOrderStatusEnum.INIT.getCode());
        confirmOrder.setTickets(JSON.toJSONString(req.getTickets()));
        confirmOrderMapper.insert(confirmOrder);

        // 发送MQ排队购票
        ConfirmOrderMQDdto confirmOrderMQDdto = new ConfirmOrderMQDdto();
        confirmOrderMQDdto.setLogId(MDC.get("LOG_ID"));
        confirmOrderMQDdto.setDate(req.getDate());
        confirmOrderMQDdto.setTrainCode(req.getTrainCode());
        String reqJson = JSON.toJSONString(confirmOrderMQDdto);
        log.info("排队购票，发送mq开始，消息：{}", reqJson);
        rocketMQTemplate.convertAndSend(RocketMQTopicEnum.CONFIRM_ORDER.getCode(), reqJson);
        log.info("排队购票，发送mq结束");

        return confirmOrder.getId();
    }
    /*
     * 需要包含限流方法的所有参数和BlockException参数
     * */
    public void doConfirmBlock(ConfirmOrderDoReq  req, BlockException e){
        log.info("购票被限流:{}", req);
        throw new BusinessException(BusinessExceptionEnum.CONFIRM_ORDER_FLOW_EXCEPTION);
    }
}
